<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"> <meta name="viewport" content="width=device-width">
    <title>一些增强图像分类中数据集的方法</title>
    <meta name="viewport" content="width=device-width,initial-scale=1, shrink-to-fit=no">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet"
          href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.min.css"
          integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
          crossorigin="anonymous">
    <link rel="stylesheet"
          href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/androidstudio.min.css">
<!--    <link rel="stylesheet" href="/web_template_css.css">-->
    <!-- this is highlight.js -->
    <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
    <script id="MathJax-script" async
            src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
    </script>
    <script  src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
    integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
    integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/js/bootstrap.min.js"
    integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
    <style>
      img{
        display: block;
        height: auto;
        max-width: 100%;
      }
    </style>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="#">kvrmnks</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav">
            <li class="nav-item active">
              <a class="nav-link" href="./../../../../../index.html" target="_self">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="./../../../../../blog.html">Blog</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="./../../../../../about.html">About</a>
            </li>
          </ul>
        </div>
      </nav>



    <div class='container'>
      <p>为了使模型具有更强的鲁棒性，一种常用的方法就是增强训练模型时的数据集，让模型学习更加鲁棒，虽然这听起来十分暴力，但是不失为一种很有效的办法。</p>

<p>你的测试集就是我的训练集（</p>

<p>就以目前在做的project为例介绍一下一些增强数据集的小办法</p>

<hr>

<h2>图像缩放</h2>

<p>以汉字识别为例，原始的图片可能是这样子的</p>

<p><img src="image-20200814230958897.png" alt="image-20200814230958897"></p>

<p>我们需要让这个汉字看起来小一点，像是这样</p>

<p><img src="image-20200814231045851.png" alt="image-20200814231045851"></p>

<p>也可能需要这个汉字看起来大一点，像是这样</p>

<p><img src="image-20200814231122270.png" alt="image-20200814231122270"></p>

<p>我们仍然采用<a href="../../blog/%E6%B5%85%E8%B0%88pytorch%E5%8A%A0%E8%BD%BD%E5%9B%BE%E7%89%87%E4%BD%9C%E4%B8%BA%E8%AE%AD%E7%BB%83%E6%95%B0%E6%8D%AE%E7%9A%84%E4%B8%80%E7%A7%8D%E5%A7%BF%E5%8A%BF/index.md">浅谈pytorch加载图片作为训练数据的一种姿势</a>中对读入图片做预处理的方式，来自己写一个class来随机缩放图片。</p>

<p>基本的思路就是，确定一个缩放比例的上下界，在这个上下界之间随机一个大小，如果要缩小就把图片缩小周围补上空白，如果放大就先把图片放大，然后从中间截取出需要的大小。</p>

<p>废话少说直接上代码</p>

<pre><code class="language-python">from torchvision import transforms
class picPull():
    def __init__(self, output_size):
        self.os = output_size
        self.lower_bound = lower_bound
        self.upper_bound = upper_bound
    def __call__(self, img):
        choice = random.uniform(self.upper_bound, self.upper_bound)
        img = MyResize(int(self.os[0]*choice), int(self.os[1]*choice)).__call__(img)
        if choice &lt; 1:
            ret = Image.new(&#39;L&#39;, (self.os[0], self.os[1]), 255)
            ret.paste(img, (int((self.os[0]-self.os[0]*choice)/2),int((self.os[1]-self.os[1]*choice)/2)))
            return ret
        else:
            ret = transforms.CenterCrop(self.os).__call__(img)
            return ret
</code></pre>

<p>其中可能有两个奇怪的东西，第一个是MyResize，见<a href="../../blog/%E6%B5%85%E8%B0%88pytorch%E5%8A%A0%E8%BD%BD%E5%9B%BE%E7%89%87%E4%BD%9C%E4%B8%BA%E8%AE%AD%E7%BB%83%E6%95%B0%E6%8D%AE%E7%9A%84%E4%B8%80%E7%A7%8D%E5%A7%BF%E5%8A%BF/index.md">浅谈pytorch加载图片作为训练数据的一种姿势</a>，第二个是transforms.CenterCrop，这是torchvision中自带的中心截取，更多的方法见<a href="https://blog.csdn.net/weixin_38533896/article/details/86028509">Pytorch：transforms的二十二个方法</a></p>

<hr>

<h2>图片随机旋转</h2>

<p>幸运的是，torchvision自带了给图片随机旋转的方法，transforms.RandomRotation(degrees, fill=)，这里要注意，如果不写fill的话，在灰度图的模式下默认填补为黑色，像这样</p>

<p><img src="image-20200814232151315.png" alt="image-20200814232151315"></p>

<p>如果想补位白色就把fill参数调整为255，效果像这样</p>

<p><img src="image-20200814232229341.png" alt="image-20200814232229341"></p>

<hr>

<h2>图片翻转</h2>

<p>包括了图像左右翻转，上下翻转</p>

<p>和随机旋转一样，torchvision也自带了一些方法</p>

<p>transforms.RandomHorizontalFlip 和 transforms.RandomVerticalFlip</p>

<p>太困了，不写了（</p>

<hr>

<p>更新了更新了 现在是2020.9.20 还把之前的一个小错误给改了</p>

<p>然后加了个完成的方便以后用？</p>

<pre><code class="language-python">from PIL import Image
import data
import numpy as np
import matplotlib.pyplot as plt
import random
from torchvision import transforms
class MyResize(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def __call__(self, img):
        raw_width, raw_height = img.size
        ratio = min(self.height/raw_height, self.width/raw_width)
        twidth, theight = (min(int(ratio * raw_width), self.width - 15), min(int(ratio * raw_height), self.height - 15))
        img = img.resize((twidth, theight), Image.ANTIALIAS)
        # 拼接图片，补足边框 居中
        ret = Image.new(&#39;L&#39;,(self.width, self.height), 255)
        ret.paste(img, (int((self.width-twidth)/2),int((self.height-theight)/2)))
        return ret
from torchvision import transforms
class picPull():
    def __init__(self, output_size, lower_bound, upper_bound):
        self.os = output_size
        self.lower_bound = lower_bound
        self.upper_bound = upper_bound
    def __call__(self, img):
        choice = random.uniform(self.lower_bound, self.upper_bound)
        img = MyResize(int(self.os[0]*choice), int(self.os[1]*choice)).__call__(img)
        if choice &lt; 1:
            ret = Image.new(&#39;L&#39;, (self.os[0], self.os[1]), 255)
            ret.paste(img, (int((self.os[0]-self.os[0]*choice)/2),int((self.os[1]-self.os[1]*choice)/2)))
            return ret
        else:
            ret = transforms.CenterCrop(self.os).__call__(img)
            return ret
tf = transforms.Compose([
    MyResize(64, 64),
    picPull((64, 64), 0.5, 1.5),transforms.RandomRotation(180, fill=255),
    transforms.RandomHorizontalFlip(0.5),
    transforms.RandomVerticalFlip(0.5),
    transforms.RandomResizedCrop((64,64), scale=(0.6, 1.4), ratio=(0.75,1.25)),
    transforms.ToTensor()
])
</code></pre>


    </div>
    <script>
      hljs.initHighlightingOnLoad()
    </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.5.0/highlightjs-line-numbers.min.js"></script>
  <script>
      hljs.initHighlightingOnLoad();
      hljs.initLineNumbersOnLoad();
  </script>
  </body>
</html>